home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
program
/
wdj0796.zip
/
CC.ZIP
/
CC.C
next >
Wrap
C/C++ Source or Header
|
1994-02-02
|
43KB
|
1,300 lines
/* Note: this source code is really crappy, but it was written in
* a big hurry.
*/
/* SS != DS if DLL, fix for bcc and ztc */
/* disabling smart callbacks for bcc and ztc */
/*
* cc - Vendor-independent interface to C compilers.
*
* to build me, type "cc -dos -wild cc.c".
*/
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <process.h>
#include <dos.h>
int Version = 0x0009;
#if defined(__BORLANDC__)
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#define WRITE write
#define OPEN open
#define CLOSE close
#define UNLINK unlink
#define STRICMP stricmp
#define CREAT creat
#elif defined(__ZTC__)
#include <io.h>
#define WRITE write
int _okbigbuf = 0; /* makes more memory available */
#define STRICMP strcmpl
#define spawnvp(a,b,c) spawnvp(a,b,(const char * const *)c)
#define execvp(b,c) execvp(b,(const char * const *)c)
#elif defined(_MSC_VER)
#include <io.h>
/* #include <sys\stat.h> */
/* #include <fcntl.h> */
#define OPEN open
#define CLOSE close
#define UNLINK unlink
#define CREAT creat
#define WRITE _write
#define STRICMP _stricmp
#endif
#define TRUE 1
#define FALSE 0
const char *Extensions = "c\0cpp\0res\0rc\0def\0obj\0lib\0lib0\0lib1\0\0";
enum { EXT_C=0, EXT_CPP, EXT_RES, EXT_RC, EXT_DEF, EXT_OBJ,
EXT_LIB, EXT_LIB0, EXT_LIB1, N_EXT };
typedef struct COMPILE_OPTIONS
{
int ProcessorType; /* 0=8088, 1=80186, etc. */
int Align; /* 1=byte align, 2=word align, etc. */
int CompileOnly; /* TRUE if compile only, no link */
char MemoryModel; /* 't' = tiny, 's' = small, etc. */
int SsNeqDs; /* TRUE if should assume SS != DS */
int Windows; /* TRUE = Windows, FALSE = DOS */
int Dll; /* TRUE = make .dll */
int Com; /* TRUE = make .com (for DOS) */
int Debug; /* 0=no debug, 1=line numbers, 2=all */
int StackCheck; /* TRUE=compile stack checks in */
int CPlusPlus; /* TRUE if using C++ instead of C */
char *RunName; /* Name to use for executable file */
int Windows30; /* TRUE if mark exe/dll for Windows 3.0 */
int MapFile; /* TRUE if we should generate map file */
int Verbose; /* TRUE if we are verbose! */
int WildCards; /* TRUE if command-line should handle wild-cards */
char Prologue; /* 'a' = AX, 's' = SS, 'd' = DGROUP, '\0' = default */
int NoSmart; /* TRUE if user wants no smart callbacks */
char *CodeSegment; /* name of code segment */
int Optimize; /* zero means no optimize */
char *LibName; /* name of library to update */
int Strict; /* =1 -> user did -DSTRICT
=0 -> user did nothing
=-1 -> user did -D */
} COMPILE_OPTIONS;
enum COMPILER_TYPE { MSC, BCC, SC };
typedef void (*COMPILER_FUNC) (enum COMPILER_TYPE , COMPILE_OPTIONS *);
typedef struct COMPILER
{
char *CompilerName;
enum COMPILER_TYPE CompilerType;
COMPILER_FUNC CompilerFunc;
} COMPILER;
void Msc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
void Bcc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
void Ztc(enum COMPILER_TYPE, COMPILE_OPTIONS *);
COMPILER Compilers[] =
{
{ "msc", MSC, Msc },
{ "bcc", BCC, Bcc },
{ "sc", SC, Ztc },
};
#define NCOMPILERS (sizeof(Compilers) / sizeof(COMPILER))
#define MAX_FILES 128
#define MAX_MACROS 128
int NMacros;
char *Macros[MAX_MACROS];
char *DefName;
char CommandLine[128];
char *UsageMessage =
"cc - Vendor-independent C/C++ Compilation (Windows/DOS Developer's Journal)\0"
"Usage: cc [options] sourcefiles\0"
"\0"
"-1 use 80186 instructions\0"
"-2 use 80286 instructions\0"
"-3 use 80386 instructions\0"
"-4 use 80486 instructions\0"
"-30 mark exe/dll 3.0 compatible\0"
"-a{1|2} byte or word alignment\0"
" (default is byte alignment)\0"
"-c compile only, no link\0"
"-com create .com (DOS only)\0"
"-C disable smart callbacks\0"
"-d include complete debug info\0"
"-dl include line numbers only\0"
"-Dname{=def} define macro\0"
"-dos compile/link for DOS\0"
"-mx{!} specify memory model:\0"
" t = tiny s = small\0"
" c = compact m = medium\0"
" l = large h = huge\0"
" ! means assume DS != SS\0"
" (the default for .dll)\0"
"-M don't generate map file\0"
"-NT<name> set name of code segment\0"
"-o<name> set name of target executable\0"
" name must end in .com, .exe, or .dll\0"
"-O optimize generated code\0"
"-p use C++ compiler\0"
"-s enable stack checks\0"
"-u<libname> Update library with .obj files\0"
"-v Verbose (don't delete .rsp files)\0"
"-w{e|d}{a|s|d}\0"
" | | (.exe default is SS)\0"
" | | (.dll default is DGROUP)\0"
" | +-> a=AX, s=SS, d=DGROUP\0"
" +-> e=.exe (default), d=.dll\0"
" default is -we (Windows .exe, use SS)\0"
"-wild link with special wildcard .obj\0"
"\0"
;
#define MAX_ARGS (64)
int NCmdArgs = 1;
char *CmdArgs[MAX_ARGS];
#include "common.c"
FileType FilesByExt[N_EXT];
FILE *OpenFile(const char *FileName, const char *Mode)
{
FILE *File;
File = fopen(FileName, Mode);
if(File == NULL)
{
fprintf(stderr, "Can't open '%s' for %s.\n", FileName,
(*Mode == 'w') ? "writing" : "reading");
exit(EXIT_FAILURE);
}
return File;
}
/* GetCompiler() return which vendor's compiler to use. */
COMPILER *GetCompiler(void)
{
char Buffer[64];
char *CC;
int i;
CC = getenv("CC");
if(CC && *CC)
{
char *Output = Buffer;
while(*CC != ' ' && *CC != '\0')
*Output++ = *CC++ | ' '; /* lowercase it */
*Output = '\0';
while(*CC == ' ')
++CC;
if(*CC)
CmdArgs[NCmdArgs++] = CC;
for(i = 0; i < NCOMPILERS; ++i)
if(!strcmp(Buffer, Compilers[i].CompilerName))
return &Compilers[i];
fprintf(stderr, "'%s': I do not recognize this compiler name "
"(defined in your\n"
" 'CC' environment variable. The names I recognize are:\n"
" ",
getenv("CC"));
for(i = 0; i < NCOMPILERS; ++i)
{
fprintf(stderr, "'%s'", Compilers[i].CompilerName);
if(i == (NCOMPILERS-2))
fprintf(stderr, " and ");
else if(i < (NCOMPILERS-1))
fprintf(stderr, ", ");
}
fprintf(stderr, "\n");
}
return 0;
}
void Usage(void)
{
int NLines;
char *Line1, *Line2;
Line1 = UsageMessage;
while(strlen(Line1)) /* blank line signals start of two-column */
{
fprintf(stderr, "%s\n", Line1);
Line1 += strlen(Line1)+1;
}
Line2 = ++Line1;
for(NLines = 0; strlen(Line2); ++NLines)
Line2 += strlen(Line2)+1;
Line2 = Line1;
NLines /= 2;
while(NLines-- > 0) /* Count total # of option lines */
Line2 += strlen(Line2)+1;
do {
int Column;
fprintf(stderr, " %s", Line1);
for(Column = strlen(Line1); Column < 36; ++Column)
fprintf(stderr, " ");
fprintf(stderr, "%s\n", Line2);
Line1 += strlen(Line1)+1;
if(*Line2)
Line2 += strlen(Line2)+1;
} while(*Line2);
exit(EXIT_FAILURE);
}
void ErrorOption(char *Arg)
{
ErrorOutput("'");
ErrorOutput(Arg);
ErrorOutput("': Unknown option\r\n");
}
int Do